<!DOCTYPE html>
<html lang="zh-cn">
  <head>
    <!-- Meta, title, CSS, favicons, etc. -->
    <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="文档管理">
<meta name="author" content="文档管理">
<title>语法指南 文档管理</title>
<link href="./assets/css/bootstrap.min.css" rel="stylesheet">
<!-- Documentation extras -->
<link href="./assets/css/docs.css" rel="stylesheet">
<link href="./assets/css/style.css" rel="stylesheet">
<link href="http://cdn.bootcss.com/highlight.js/7.3/styles/github.min.css" rel="stylesheet">
<style>
body{font-family:"ff-tisa-web-pro-1","ff-tisa-web-pro-2","Lucida Grande","Helvetica Neue",Helvetica,Arial,"Hiragino Sans GB","Hiragino Sans GB W3","WenQuanYi Micro Hei",sans-serif;}
h1, .h1, h2, .h2, h3, .h3, h4, .h4, .lead {font-family:"ff-tisa-web-pro-1","ff-tisa-web-pro-2","Lucida Grande","Helvetica Neue",Helvetica,Arial,"Hiragino Sans GB","Hiragino Sans GB W3","Microsoft YaHei UI","Microsoft YaHei","WenQuanYi Micro Hei",sans-serif;}
pre code { background: transparent; }
@media (min-width: 768px) {
    .bs-docs-home .bs-social, 
    .bs-docs-home .bs-masthead-links {
      margin-left: 0;
    }
}
.bs-docs-section p {
	line-height: 2;
}
.bs-docs-section p.lead {
	line-height: 1.4;
}
</style>
<!--[if lt IE 9]><script src="../docs-assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
  <script src="http://cdn.bootcss.com/html5shiv/3.7.0/html5shiv.min.js"></script>
  <script src="http://cdn.bootcss.com/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
<!-- Favicons -->
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="../docs-assets/ico/apple-touch-icon-144-precomposed.png">
<link rel="shortcut icon" href="../docs-assets/ico/favicon.png">
  </head>
  <body>
    <a class="sr-only" href="#content">Skip to main content</a>

    <!-- Docs master nav -->
    <header class="navbar navbar-inverse navbar-fixed-top bs-docs-nav" role="banner">
  <div class="container">
    <div class="navbar-header">
      <button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".bs-navbar-collapse">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a href="./overview.html" class="navbar-brand">文档管理</a>
    </div>
    <nav class="collapse navbar-collapse bs-navbar-collapse" role="navigation">
      <ul class="nav navbar-nav">
       		<li  ><a href="overview.html">简介</a></li>
            <li ><a href="download.html">下载</a></li>
            <li ><a href="userguide.html">开发指南</a></li>
            <li ><a href="config.html">配置指南</a></li>
            <li class='active'><a href="syntax.html" class="selected">语法指南</a></li>
            <li ><a href="integrate.html">Web 框架集成</a></li>
            <!--
            <li ><a href="example.html">例子</a></li>
            -->
            <li ><a href="faq.html">FAQ</a></li>
            <li ><a href="about.html">关于</a></li>
      </ul>
    </nav>
  </div>
</header>
    <!-- Docs page layout -->
    <div class="bs-header" id="content">
      <div class="container">
        <h2>语法指南</h2>
        <p></p>
      </div>
    </div>
	<a href="#top" id="toTop"></a>
    <!-- Callout for the old docs link -->
    <div class="container bs-docs-container">
      <div class="row">
        <div class="col-md-3">
          <div class="bs-sidebar hidden-print" role="complementary">
            <ul class="nav bs-sidenav">
            <li><a href="#x1812010899">1 值 Value</a></li>
            <li><a href="#x97152884">2 指令 Directive</a></li>
            <li><a href="#x1765529987">&nbsp&nbsp2.1 变量类型声明 #define</a></li>
            <li><a href="#x31238794">&nbsp&nbsp2.2 赋值语句 #set</a></li>
            <li><a href="#x31241181">&nbsp&nbsp2.3 赋值语句 #put</a></li>
            <li><a href="#x1615167792">&nbsp&nbsp2.4 条件语句 #if, #elseif, #else</a></li>
            <li><a href="#x719310441">&nbsp&nbsp2.5 循环语句 #for</a></li>
            <li><a href="#x520315191">&nbsp&nbsp2.6 循环中断或继续语句 #break, #continue</a></li>
            <li><a href="#x1448344112">&nbsp&nbsp2.7 停止解析语句 #stop</a></li>
            <li><a href="#x347886788">&nbsp&nbsp2.8 嵌套模板语句 #include</a></li>
            <li><a href="#x778876459">&nbsp&nbsp2.9 宏定义 #macro</a></li>
            <li><a href="#x1007843513">&nbsp&nbsp2.10 自定义标签 #tag</a></li>
            <li><a href="#x890125816">3 文本 Text</a></li>
            <li><a href="#x136317352">&nbsp&nbsp3.1 不解析文本块</a></li>
            <li><a href="#x1841434365">&nbsp&nbsp3.2 特殊字符转义</a></li>
            <li><a href="#x1221926399">4 注释 Comment</a></li>
            <li><a href="#x34432814">&nbsp&nbsp4.1 行注释</a></li>
            <li><a href="#x22388601">&nbsp&nbsp4.2 块注释</a></li>
            <li><a href="#x750650433">5 表达式 Expression</a></li>
            <li><a href="#x948751994">&nbsp&nbsp5.1 变量名 Variable</a></li>
            <li><a href="#x1847340345">&nbsp&nbsp5.2 List 常量</a></li>
            <li><a href="#x1996788741">&nbsp&nbsp5.3 Map 常量</a></li>
            <li><a href="#x394735919">&nbsp&nbsp5.4 Bean 属性调用 bean.property</a></li>
            <li><a href="#x1481011027">&nbsp&nbsp5.5 Bean 方法调用 bean.method(...)</a></li>
            <li><a href="#x134013728">&nbsp&nbsp5.6 函数调用 function</a></li>
            <li><a href="#x502090105">&nbsp&nbsp5.7 静态字段调用 @Class.Field</a></li>
            <li><a href="#x1814113504">&nbsp&nbsp5.8 静态方法调用 @Class.method</a></li>
            <li><a href="#x2038510066">6 默认的方法扩展 Methods</a></li>
            <li><a href="#x781953175">&nbsp&nbsp6.1 基本数据类型转换 Cast</a></li>
            <li><a href="#x1169187945">&nbsp&nbsp6.2 集合类型转换 Cast</a></li>
            <li><a href="#x355317298">&nbsp&nbsp6.3 数据格式化 Format</a></li>
            <li><a href="#x1727847930">&nbsp&nbsp6.4 数据 Escape/Unescape</a></li>
            <li><a href="#x14779721">&nbsp&nbsp6.5 默认值输出</a></li>
            <li><a href="#x591511809">&nbsp&nbsp6.6 JSON 输出</a></li>
            <li><a href="#x1079447065">&nbsp&nbsp6.7 字符串转换</a></li>
            <li><a href="#x969081998">&nbsp&nbsp6.8 算术计算</a></li>
            <li><a href="#x1154836530">7 默认的函数扩展 Functions</a></li>
            <li><a href="#x748057859">&nbsp&nbsp7.1 常用函数</a></li>
            <li><a href="#x665841341">&nbsp&nbsp7.2 循环计数生成器</a></li>
            <li><a href="#x958665306">&nbsp&nbsp7.3 嵌入子模板 include(...)</a></li>
            <li><a href="#x1231948809">&nbsp&nbsp7.4 嵌入纯文本文件 read(...)</a></li>
            <li><a href="#x1292645738">&nbsp&nbsp7.5 调试专用函数 debug(...)</a></li>
            <li><a href="#x117672627">&nbsp&nbsp7.6 Web 路径获取 ctxpath() / webroot()</a></li>
            <li><a href="#x1937656097">8 默认的自定义标签 Tags</a></li>
            <li><a href="#x1968843044">9 和 Velocity 的比较</a></li>
            <li><a href="#x1094687580">&nbsp&nbsp9.1 语法差异</a></li>
            <li><a href="#x775409745">&nbsp&nbsp9.2 指令差异</a></li>
            </ul>
          </div>
        </div>
	        <div class="col-md-9" role="main">
	         <div class="bs-docs-section">
	           <p>这个是 <code>jetbrick-template</code> 模板语法参考手册。我们推荐的模板文件扩展名为 <code>.jetx</code>，嵌入式子模板的扩展名为 <code>.inc.jetx</code>。</p>
<h1 id="x1812010899" class="page-header"><span>1 值 Value</span></h1>
<p>语法：</p> 
<ul> 
 <li><code>${expression}</code>：输出表达式的计算结果。</li> 
 <li><code>$!{expression}</code>：输出表达式的计算结果，并 escape 其中的 HTML 标签。</li> 
</ul>
<p>其中 <code>expression</code> 为任何合法的 Java 表达式，参考: <a href="#expression">表达式</a>。</p>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">${user.name}
${user.book.available()}
$!{user.description}
</code></pre>
</div> 
<blockquote>
 <p><strong>注意</strong>：</p> 
 <ul> 
  <li>如果 <code>expression</code> 为 <code>null</code>，则不会输出任何东西，如果需要输出 <code>null</code>，可以使用如下的方法扩展：<code>${expression.asString()}</code>。</li> 
  <li>如果 <code>expression</code> 的返回类型为 <code>void</code>，那么也不会做任何输出动作。</li> 
 </ul> 
</blockquote>
<h1 id="x97152884" class="page-header"><span>2 指令 Directive</span></h1>
<h2 id="x1765529987" class="page-header"><span>2.1 变量类型声明 #define</span></h2>
<p>jetbrick-template 为了提高性能，采用了强类型来编译模板，所以需要为每一个用到的变量定义变量类型。如下：</p>
<p>语法：</p> 
<ul> 
 <li><code>#define(type name, ...)</code></li> 
</ul>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">#define(String name)
#define(UserInfo user, List&lt;UserInfo&gt; userlist)
</code></pre>
</div> 
<blockquote>
 <p><strong>注意</strong>：</p> 
 <ul> 
  <li>在相同作用域下面，不允许重复定义变量类型，变量只在当前作用域有效。</li> 
  <li>对于没有定义变量类型，默认作用域为全局有效(Global)。</li> 
  <li>对于没有定义变量类型，那么优先从上下文表达式中进行类型推导, 否则默认类型为 <code>Object</code>。</li> 
 </ul> 
</blockquote>
<h2 id="x31238794" class="page-header"><span>2.2 赋值语句 #set</span></h2>
<p>语法：</p> 
<ul> 
 <li><code>#set(type name = value, ...)</code></li> 
 <li><code>#set(name = value, ...)</code></li> 
</ul>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">#set(int num = 1+2*3)
#set(color1 = &quot;#ff0000&quot;, color2 = &quot;#00ff00&quot;)
</code></pre>
</div> 
<blockquote>
 <p><strong>注意</strong>：</p> 
 <ul> 
  <li>在相同作用域下面，不允许重复定义变量类型，变量只在当前作用域有效。</li> 
  <li>影响当前模板，以及子模板的 <code>JetContext</code> 变量。</li> 
  <li>不影响父模板的 <code>JetContext</code> 变量。</li> 
 </ul> 
</blockquote>
<h2 id="x31241181" class="page-header"><span>2.3 赋值语句 #put</span></h2>
<p>将变量内容保存到当前模板以及所有父模板的 <code>JetContext</code> 中，方便父子模板间进行变量传递。</p>
<p>语法：</p> 
<ul> 
 <li><code>#put(name, value)</code></li> 
 <li><code>#put(name1, value1, name2, value2, ...)</code></li> 
</ul>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">#put(&quot;num&quot;, 1 + 2 * 3)
#put(&quot;user&quot;, user, &quot;name&quot;, &quot;jetbrick&quot;)
</code></pre>
</div> 
<blockquote>
 <p><strong>注意</strong>：</p> 
 <ul> 
  <li>可以传递多个 key-value 对</li> 
  <li>参数 <code>name</code> 必须是 <code>String</code> 类型</li> 
 </ul> 
</blockquote>
<h2 id="x1615167792" class="page-header"><span>2.4 条件语句 #if, #elseif, #else</span></h2>
<p>如果 <code>#if</code> 条件表达式计算结果为 <code>true</code> 或非空，则输出指令所包含的块, 否则输出 <code>#else</code> 指令块。</p>
<p>语法：</p> 
<ul> 
 <li><code>#if(expression)</code> ... <code>#end</code></li> 
 <li><code>#if(expression)</code> ... <code>#else</code> ... <code>#end</code></li> 
 <li><code>#if(expression)</code> ... <code>#elseif(expression)</code> ... <code>#else</code> ... <code>#end</code></li> 
</ul>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">#if (user.role == &quot;admin&quot;)
	...
#elseif (user.role == &quot;vip&quot;)
	...
#elseif (user.role == &quot;guest&quot;)
	...
#else
	...
#end
</code></pre>
</div> 
<blockquote>
 <p><strong>注意</strong>：</p> 
 <ul> 
  <li>对于 <code>expression</code> 为非 <code>Boolean</code> 值：非零数字，非空字串，非空集合，非 <code>null</code> 对象，即为 <code>true</code>。</li> 
  <li><code>#elseif</code> 允许出现多次。</li> 
  <li>如果 <code>#else</code> 后面紧跟着其他文本，比如 <code>#elseABC</code>，那么可以通过添加一对空括号来分割，修改成 <code>#else()ABC</code>。这样可读性就能加强，模板解析也不会出现问题。所有的无参数指令，比如 <code>#end</code>，<code>#break</code>，<code>#stop</code> 都支持这样操作。<code>()</code> 前面和之间请不要插入任何空格。</li> 
 </ul> 
</blockquote>
<h2 id="x719310441" class="page-header"><span>2.5 循环语句 #for</span></h2>
<p>循环重复输出指令所包含的块，如果是空的集合对象，那么输出 <code>#else</code> 块。</p>
<p>语法：</p> 
<ul> 
 <li><code>#for(id: expression)</code> ... <code>#end</code></li> 
 <li><code>#for(id: expression)</code> ... <code>#else</code> ... <code>#end</code></li> 
 <li><code>#for(type id: expression)</code> ... <code>#end</code></li> 
 <li><code>#for(type id: expression)</code> ... <code>#else</code> ... <code>#end</code></li> 
</ul>
<p><code>#for</code> 支持以下类型的 <code>expression</code></p> 
<ul> 
 <li>Iterator</li> 
 <li>Iterable (Collection, ...)</li> 
 <li>Map</li> 
 <li>Enumeration</li> 
 <li>Array</li> 
 <li>null (空循环)</li> 
 <li>Object (只循环一次)</li> 
</ul>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">#for (book : user.books)
	${for.index} // 内部循环计数器，从 1 开始计数
	...
#end
</code></pre>
</div>
<p>循环变量 id 类型声明，用作强制转型，避免类型推导失败。</p> 
<div class="highlight">
 <pre><code class="language-html">#for (Book book : user.books)
	...
#end
</code></pre>
</div>
<p>指令 <code>#else</code> 可用于循环为空时的内容输出。</p> 
<div class="highlight">
 <pre><code class="language-html">#for (Book book : user.books)
	...
#else
	No books are found in here.
#end
</code></pre>
</div>
<h3 id="x1058087874" class="page-header"><span>2.5.1 for 内部对象</span></h3> 
<ul> 
 <li><code>for.index</code> 可用于内部循环计数，从 1 开始计数。</li> 
 <li><code>for.size</code> 获取循环总数。如果对 Iterator 进行循环，或者对非 Collection 的 Iterable 进行循环，则返回 -1。</li> 
 <li><code>for.first</code> 是否第一个元素。</li> 
 <li><code>for.last</code> 是否最后一个元素。</li> 
 <li><code>for.odd</code> 是否第奇数个元素。</li> 
 <li><code>for.even</code> 是否第偶数个元素。</li> 
</ul>
<h2 id="x520315191" class="page-header"><span>2.6 循环中断或继续语句 #break, #continue</span></h2>
<p>当 <code>expression</code> 为 <code>true</code>，<code>#break</code> 中断当前循环，而 <code>#continue</code> 跳过余下的内容，跳到下一个循环。</p>
<p>语法：</p> 
<ul> 
 <li><code>#break</code></li> 
 <li><code>#break(expression)</code></li> 
 <li><code>#continue</code></li> 
 <li><code>#continue(expression)</code></li> 
</ul>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">#for (book : user.books)
	...
	#break(book.price &gt; 100)
	...
#end
</code></pre>
</div> 
<div class="highlight">
 <pre><code class="language-html">#for (book : user.books)
	...
	#continue(book.price &gt; 100)
	...
#end
</code></pre>
</div> 
<blockquote>
 <p><strong>注意</strong>：</p> 
 <ul> 
  <li>无参数格式代表 <code>expression</code> 永远为 <code>true</code>。</li> 
 </ul> 
</blockquote>
<h2 id="x1448344112" class="page-header"><span>2.7 停止解析语句 #stop</span></h2>
<p>当 <code>expression</code> 为真或非空时，停止模板运行。</p>
<p>语法：</p> 
<ul> 
 <li><code>#stop</code></li> 
 <li><code>#stop(expression)</code></li> 
</ul>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">#stop(error != null)
</code></pre>
</div> 
<blockquote>
 <p><strong>注意</strong>：</p> 
 <ul> 
  <li>无参数格式代表 <code>expression</code> 永远为 <code>true</code>。</li> 
 </ul> 
</blockquote>
<h2 id="x347886788" class="page-header"><span>2.8 嵌套模板语句 #include</span></h2>
<p>嵌入一个子模板，将子模板内容输出到当前位置。</p>
<p>语法：</p> 
<ul> 
 <li><code>#include(file)</code></li> 
 <li><code>#include(file, parameters)</code></li> 
</ul>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">#include(&quot;/include/header.jetx&quot;) // 绝对路径
#include(&quot;../userinfo.jetx&quot;) // 相对路径
#include(file) // 动态路径
#include(&quot;/include/header.jetx&quot;, {role: &quot;admin&quot;}) // 传递参数
</code></pre>
</div> 
<blockquote>
 <p><strong>注意</strong>：</p> 
 <ul> 
  <li>子模板自动共享父模板 <code>JetContext</code> 变量，同时还可以另外传递一些参数给子模板。</li> 
  <li>子模板可以用 <code>#put</code> 指令修改父模板的 <code>JetContext</code>，然后在父模板中用 <code>context[&quot;name&quot;]</code> 获取变量值。</li> 
 </ul> 
</blockquote>
<p>具体用法请查考： <a href="faq-include.html">在 jetbrick-template 中如何使用 #include？</a></p>
<h2 id="x778876459" class="page-header"><span>2.9 宏定义 #macro</span></h2>
<p>定义一个代码片段，然后可以重复使用。(New from 1.1.0)</p>
<p>语法：</p> 
<ul> 
 <li><code>#macro name(type name, ...)</code> ... <code>#end</code></li> 
</ul> 
<blockquote>
 <p><strong>注意</strong>： 每个宏可以定义 0~N 个参数。</p> 
</blockquote>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">#macro header(String name)
    Hello ${name}!
#end

${header(&quot;张三&quot;)}
${header(&quot;李四&quot;)}
</code></pre>
</div>
<p>输出结果：</p> 
<div class="highlight">
 <pre><code class="language-html">    Hello 张三!
    Hello 李四!
</code></pre>
</div> 
<blockquote>
 <p><strong>注意</strong>：</p> 
 <ul> 
  <li>宏的调用就和函数调用一样。(如果和函数存在名称冲突，那么宏定义优先)</li> 
  <li>宏的调用返回值是 Void，所以不支持对返回值进行计算。</li> 
 </ul> 
</blockquote>
<h2 id="x1007843513" class="page-header"><span>2.10 自定义标签 #tag</span></h2>
<p>jetbrick-template 支持自定义 Tag，类似于 JSP Taglib，但是要比 JSP Taglib 更简单更好用。(New from 1.1.0)</p>
<p>语法：</p> 
<ul> 
 <li><code>#tag name(args ...)</code> ... <code>#end</code></li> 
</ul> 
<blockquote>
 <p><strong>注意</strong>： </p> 
 <ul> 
  <li>需要在 Java 端先定义 Tag 标签的实现。</li> 
  <li>Tag 调用的参数必须和定义的一致。</li> 
 </ul> 
</blockquote>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">#tag layout(&quot;layout.jetx&quot;)
    Hello ${name}!
#end
</code></pre>
</div>
<p>具体用法请查考： <a href="faq-tag.html">在 jetbrick-template 中如何自定义 Tag？</a></p>
<h1 id="x890125816" class="page-header"><span>3 文本 Text</span></h1>
<p>普通文本内容将会被直接进行输出。</p>
<h2 id="x136317352" class="page-header"><span>3.1 不解析文本块</span></h2>
<p>原样输出模板内容，用于输出纯文本内容，或批量转义块中的特殊字符。类似于 XML 中的 CDATA。</p>
<p>语法：</p> 
<ul> 
 <li><code>#[[</code> ... <code>]]#</code></li> 
</ul>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">#[[
	Source code will be displayed in here.
	Hello ${user.name}	
]]#
</code></pre>
</div>
<h2 id="x1841434365" class="page-header"><span>3.2 特殊字符转义</span></h2>
<p>原样输出指令特殊字符，转义字符由 <code>\</code> 进行转义。</p>
<p>语法：</p> 
<ul> 
 <li><code>\\</code></li> 
 <li><code>\#</code></li> 
 <li><code>\$</code></li> 
</ul>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">\#if
\${user.name}
\\${user.name}
</code></pre>
</div> 
<blockquote>
 <p><strong>注意</strong>：</p> 
 <ul> 
  <li>如果遇到类似 <code>#ff0000</code> 类似于指令的内容，但又不是系统定义的指令，那么也会原样输出，并不需要进行转义。</li> 
  <li><code>\</code> 后面跟的字符不是 <code>#</code> 和 <code>$</code>，也不需要进行转义，直接输出。</li> 
 </ul> 
</blockquote>
<h1 id="x1221926399" class="page-header"><span>4 注释 Comment</span></h1>
<h2 id="x34432814" class="page-header"><span>4.1 行注释</span></h2>
<p>隐藏行注释的内容，以换行符结束，用于注解过程，或屏蔽指令内容。</p>
<p>语法：</p> 
<ul> 
 <li><code>##</code> ...</li> 
</ul>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">${user.name} ## This is a line comment.
</code></pre>
</div>
<h2 id="x22388601" class="page-header"><span>4.2 块注释</span></h2>
<p>隐藏块注释内容，可包含换行符，用于注解过程，或屏蔽指令内容。</p>
<p>语法：</p> 
<ul> 
 <li><code>#--</code> ... <code>--#</code></li> 
</ul>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">#--
	This is a block comment.
--#
</code></pre>
</div>
<p><a name="expression"></a></p>
<h1 id="x750650433" class="page-header"><span>5 表达式 Expression</span></h1>
<p>支持所有 Java 表达式，并对其进行了一些有用的扩展。</p>
<h3 id="x82363453" class="page-header"><span>5.0.1 与 Java 相同的地方 (运算符优先级和 Java 保存一致)</span></h3> 
<ul> 
 <li>数字常量： <code>123</code> <code>123L</code> <code>0.01D</code> <code>99.99E-10D</code></li> 
 <li>字符串常量： <code>&quot;abc\r\n&quot;</code> <code>'abc\u00A0\r\n'</code></li> 
 <li>BOOLEAN 常量：<code>true</code> <code>false</code></li> 
 <li>NULL 常量: <code>null</code></li> 
 <li>算术运行： <code>+</code> <code>-</code> <code>*</code> <code>/</code> <code>%</code></li> 
 <li>自增/自减： <code>++</code> <code>--</code></li> 
 <li>位运算： <code>~</code> <code>&amp;</code> <code>|</code></li> 
 <li>移位运算： <code>&gt;&gt;</code> <code>&gt;&gt;&gt;</code> <code>&lt;&lt;</code></li> 
 <li>比较运算： <code>==</code> <code>!=</code> <code>&gt;</code> <code>&gt;=</code> <code>&lt;</code> <code>&lt;=</code></li> 
 <li>逻辑运算： <code>!</code> <code>&amp;&amp;</code> <code>||</code></li> 
 <li>三元表达式： <code>? :</code></li> 
 <li>实例对象判断： <code>instanceof</code></li> 
 <li>NEW 对象：<code>new Object(...)</code></li> 
 <li>强制类型转换：<code>(java.lang.String)obj</code></li> 
 <li>数组存取：<code>array[i]</code></li> 
 <li>字段访问：<code>obj.field</code></li> 
 <li>方法调用：<code>obj.method(...)</code></li> 
 <li>方法调用：支持可变参数方法(Varargs)和重载方法(Overload)</li> 
 <li>静态字段调用：<code>@Long.MAX_VALUE</code></li> 
 <li>静态方法调用：<code>@Long.valueOf(&quot;123&quot;)</code></li> 
 <li>支持数组定义：<code>String[]</code></li> 
 <li>支持泛型定义：<code>List&lt;String&gt;</code> <code>Map&lt;String[], List&lt;?&gt;&gt;</code></li> 
</ul>
<h3 id="x1957148670" class="page-header"><span>5.0.2 与 Java 不同的地方</span></h3> 
<ul> 
 <li>双等号 <code>==</code> 会被解析成 <code>equals()</code> 方法比较，而不是比内存地址。</li> 
 <li>单双引号都将生成字符串：<code>'a'</code> 或 <code>&quot;a&quot;</code> 都是<code>String</code> 类型。</li> 
 <li>Bean 属性会解析成 getter 方法调用，<code>${user.name}</code> 等价于 <code>${user.getName()}</code></li> 
 <li>所有实现 <code>Comparable</code> 的对象都支持比较运算符，比如：<code>#if(date1 &lt; date2)</code>，可以比较日期的先后。</li> 
 <li>所有对象都条件测试，并返回 <code>true</code> 或者 <code>false</code>。对于非 <code>Boolean</code> 对象，所有非零数字，非空字串，非空集合，非 <code>null</code> 对象，即为 <code>true</code>。</li> 
 <li><code>List</code> 和 <code>Map</code> 可以方括号取值，比如：<code>list[0]</code> 等价于 <code>list.get(0)</code>，<code>map[&quot;abc&quot;]</code> 等价于 <code>map.get(&quot;abc&quot;)</code>。</li> 
 <li><code>Map</code> 和 <code>JetContext</code> 对象支持 <code>.</code> 访问内部的对象（属性调用），如： <code>map.key</code>, <code>context.key</code>。</li> 
 <li>支持 Groovy 的 <code>?.</code> 安全调用，以避免 <code>NullPointerException</code>。</li> 
 <li>静态字段/方法调用，需要用 <code>@</code> 前缀，比如： <code>@Long.MAX_VALUE</code>，如果类带包名，需要这么用： <code>@(java.lang.Long).valueOf(&quot;123&quot;)</code></li> 
</ul>
<h2 id="x948751994" class="page-header"><span>5.1 变量名 Variable</span></h2>
<p>可以是任意合法的 Java 变量名：</p> 
<ul> 
 <li>其中 <code>$</code> 开头的变量为模板内部变量，不允许直接使用。</li> 
 <li>不允许使用 Java 关键字。</li> 
</ul>
<p>如：<code>user</code>, <code>user_name</code>, <code>userName</code></p>
<p>2 个内置的特殊变量：</p> 
<ul> 
 <li><code>context</code>： 当前模板的 <code>JetContext</code> 对象。</li> 
 <li><code>for</code>： 用于 <code>#for</code> 指令内部状态对象。具体参考 <code>#for</code> 指令用法。</li> 
</ul>
<h2 id="x1847340345" class="page-header"><span>5.2 List 常量</span></h2>
<p>语法：</p> 
<ul> 
 <li><code>[item, ...]</code></li> 
</ul>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">[] // empty List
[1, 2, 3, 4, 5]
[&quot;abc&quot;, 123, new Date(), 1+2*3]
</code></pre>
</div>
<p>取值：</p> 
<div class="highlight">
 <pre><code class="language-html">${list[index]}
${list.get(index)}

// 安全调用
${list?[index]}
${list?.get(index)}
</code></pre>
</div>
<h2 id="x1996788741" class="page-header"><span>5.3 Map 常量</span></h2>
<p>语法：</p> 
<ul> 
 <li><code>{key: value, ...}</code></li> 
</ul>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">{} // empty Map
{&quot;name&quot; : &quot;Jason&quot;, &quot;statue&quot; : 0}
</code></pre>
</div>
<p>取值：</p> 
<div class="highlight">
 <pre><code class="language-html">${map.key}
${map[&quot;key&quot;]}
${map.get(&quot;key&quot;)}

// 安全调用
${map?.key}
${map?[&quot;key&quot;]}
${map?.get(&quot;key&quot;)}
</code></pre>
</div>
<h2 id="x394735919" class="page-header"><span>5.4 Bean 属性调用 bean.property</span></h2>
<p>Bean 属性会解析成 getter 方法调用。</p>
<p>属性查找顺序，以 <code>${obj.foo}</code> 为例：</p> 
<ol> 
 <li>查找 obj.getFoo() 方法</li> 
 <li>查找 obj.isFoo() 方法</li> 
 <li>查找 obj class 的 foo 字段</li> 
 <li>查找 obj.get(name) 方法 (如果是 <code>Map</code> 或者 <code>JetContext</code>)</li> 
</ol>
<p>以上查找过程会在第一次编译的时候完成，不影响性能。<br />支持对属性返回值的类型推导。</p> 
<blockquote>
 <p><strong>注意</strong>： <code>jetbrick-template</code> 支持属性的安全调用，和 Groovy 相同，你可以使用 <code>?.</code> 来代替 <code>.</code>，以避免出现 <code>NullPointerException</code>。</p> 
</blockquote>
<h2 id="x1481011027" class="page-header"><span>5.5 Bean 方法调用 bean.method(...)</span></h2> 
<ul> 
 <li>支持普通方法调用</li> 
 <li>支持不定长参数方法调用 Varargs</li> 
 <li>支持方法重载 Overload</li> 
 <li>支持扩展方法调用。参考：<a href="userguide.html#methods">扩展方法调用</a></li> 
 <li>支持对方法返回值的类型推导</li> 
</ul>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">## 方法重载 Overload
${&quot;Hello&quot;.substring(2)}
${&quot;Hello&quot;.substring(2, 3)}
</code></pre>
</div> 
<blockquote>
 <p><strong>注意</strong>： <code>jetbrick-template</code> 支持方法的安全调用，和 Groovy 相同，你可以使用 <code>?.</code> 来代替 <code>.</code>，以避免出现 <code>NullPointerException</code>。</p> 
</blockquote>
<h2 id="x134013728" class="page-header"><span>5.6 函数调用 function</span></h2>
<p>jetbrick-template 还支持函数调用，如 <code>${now()}</code>, <code>${include(&quot;tag.jetx&quot;)}</code>。</p>
<p>具体参考：<a href="userguide.html#functions">扩展函数调用</a></p>
<h2 id="x502090105" class="page-header"><span>5.7 静态字段调用 @Class.Field</span></h2>
<p>(New from 1.1.0)</p>
<p>语法：</p> 
<ul> 
 <li><code>@Class.Field</code></li> 
 <li><code>@(package.Class).Field</code></li> 
</ul>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">${@Long.MAX_VALUE}
${@(java.lang.Long).MAX_VALUE}
</code></pre>
</div>
<h2 id="x1814113504" class="page-header"><span>5.8 静态方法调用 @Class.method</span></h2>
<p>(New from 1.1.0)</p>
<p>语法：</p> 
<ul> 
 <li><code>@Class.method(...)</code></li> 
 <li><code>@(package.Class).method(...)</code></li> 
</ul>
<p>示例：</p> 
<div class="highlight">
 <pre><code class="language-html">${@Collections.emptyList()}
${@(java.lang.Long).valueOf(&quot;123&quot;)}
</code></pre>
</div>
<p><a name="default_methods"></a></p>
<h1 id="x2038510066" class="page-header"><span>6 默认的方法扩展 Methods</span></h1>
<p>所有方法扩展定义在 <code>jetbrick.template.runtime.JetMethods</code></p>
<h2 id="x781953175" class="page-header"><span>6.1 基本数据类型转换 Cast</span></h2> 
<ul> 
 <li>String.asBoolean()</li> 
 <li>String.asChar()</li> 
 <li>String.asByte()</li> 
 <li>String.asShort()</li> 
 <li>String.asInt()</li> 
 <li>String.asLong()</li> 
 <li>String.asFloat()</li> 
 <li>String.asDouble()</li> 
 <li>String.asDate()</li> 
 <li>String.asDate(String format)</li> 
 <li>Object.asString()</li> 
</ul>
<h2 id="x1169187945" class="page-header"><span>6.2 集合类型转换 Cast</span></h2> 
<ul> 
 <li>Collection.asList()</li> 
 <li>boolean[].asList()</li> 
 <li>char[].asList()</li> 
 <li>byte[].asList()</li> 
 <li>short[].asList()</li> 
 <li>int[].asList()</li> 
 <li>long[].asList()</li> 
 <li>float[].asList()</li> 
 <li>doubl[].asList()</li> 
 <li>Object[].asList()</li> 
</ul>
<h2 id="x355317298" class="page-header"><span>6.3 数据格式化 Format</span></h2> 
<ul> 
 <li>Number.format()</li> 
 <li>Number.format(String format)</li> 
 <li>Date.format()</li> 
 <li>Date.format(String format)</li> 
</ul>
<h2 id="x1727847930" class="page-header"><span>6.4 数据 Escape/Unescape</span></h2> 
<ul> 
 <li>String.escapeJava()</li> 
 <li>String.unescapeJava()</li> 
 <li>String.escapeJavaScript()</li> 
 <li>String.unescapeJavaScript()</li> 
 <li>String.escapeXml()</li> 
 <li>String.unescapeXml()</li> 
 <li>String.escapeUrl()</li> 
 <li>String.escapeUrl(String encoding)</li> 
 <li>String.unescapeUrl()</li> 
 <li>String.unescapeUrl(String encoding)</li> 
</ul>
<h2 id="x14779721" class="page-header"><span>6.5 默认值输出</span></h2> 
<ul> 
 <li>Object.asDefault(Object defaultValue)</li> 
</ul>
<h2 id="x591511809" class="page-header"><span>6.6 JSON 输出</span></h2> 
<ul> 
 <li>Object.asJSON()</li> 
</ul>
<h2 id="x1079447065" class="page-header"><span>6.7 字符串转换</span></h2> 
<ul> 
 <li>String.toUnderlineName()</li> 
 <li>String.toCamelCase()</li> 
 <li>String.toCapitalizeCamelCase()</li> 
 <li>String.repeat(int count)</li> 
</ul>
<h2 id="x969081998" class="page-header"><span>6.8 算术计算</span></h2> 
<ul> 
 <li>int[].sum()</li> 
 <li>int[].avg()</li> 
 <li>int[].max()</li> 
 <li>int[].min()</li> 
</ul>
<p><a name="default_functions"></a></p>
<h1 id="x1154836530" class="page-header"><span>7 默认的函数扩展 Functions</span></h1>
<p>所有函数扩展定义在 <code>jetbrick.template.runtime.JetFunctions</code></p>
<h2 id="x748057859" class="page-header"><span>7.1 常用函数</span></h2> 
<ul> 
 <li><p><code>Date now()</code><br /> 获取当前时间</p></li> 
 <li><p><code>int random()</code><br /> 获取一个随机数</p></li> 
 <li><p><code>UUID uuid()</code><br /> 获取一个 UUID</p></li> 
</ul>
<h2 id="x665841341" class="page-header"><span>7.2 循环计数生成器</span></h2>
<p>生成一个用于循环的数组，主要用于 <code>#for</code> 的循环迭代。</p>
<p>@Deprecated from 1.0.2</p> 
<ul> 
 <li><code>int[] range(int start, int stop)</code></li> 
 <li><code>int[] range(int start, int stop, int step)</code></li> 
</ul>
<p>New added from 1.0.2</p> 
<ul> 
 <li><code>Iterator&lt;Integer&gt; iterator(int start, int stop)</code></li> 
 <li><code>Iterator&lt;Integer&gt; iterator(int start, int stop, int step)</code></li> 
</ul>
<p>范例：</p> 
<div class="highlight">
 <pre><code class="language-html">#for (int i : iterator(1,100))
	${i}
#end
</code></pre>
</div>
<h2 id="x958665306" class="page-header"><span>7.3 嵌入子模板 include(...)</span></h2>
<p>嵌入一个子模板。和 <code>#include</code> 指令的区别，此函数对子模板的输出进行了缓存，可以处理返回的内容，但是效率没有 <code>#include</code> 指令高。</p> 
<ul> 
 <li><code>String include(String relativeName)</code></li> 
 <li><code>String include(String relativeName, Map&lt;String, Object&gt; parameters)</code></li> 
</ul>
<h2 id="x1231948809" class="page-header"><span>7.4 嵌入纯文本文件 read(...)</span></h2> 
<ul> 
 <li><code>String read(String relativeName)</code></li> 
 <li><code>String read(String relativeName, String encoding)</code></li> 
</ul>
<h2 id="x1292645738" class="page-header"><span>7.5 调试专用函数 debug(...)</span></h2> 
<ul> 
 <li><code>void debug(String format, Object... args)</code><br /> 输出调试信息，需要配合 Slf4j 使用。 参数格式请查看 <a href="http://www.slf4j.org/apidocs/org/slf4j/Logger.html">Slf4j Logger</a>。</li> 
</ul>
<h2 id="x117672627" class="page-header"><span>7.6 Web 路径获取 ctxpath() / webroot()</span></h2> 
<ul> 
 <li><p><code>String ctxpath()</code><br /> 返回相对于 web 根目录的绝对路径，如 /myapp</p></li> 
 <li><p><code>String ctxpath(String url)</code><br /> 将 url 转换为相对于 web 根目录的绝对路径，如 /myapp/path/file</p></li> 
 <li><p><code>String webroot()</code><br /> 返回完整的 web 站点路径，如 <a href="http://127.0.0.1:8080/myapp">http://127.0.0.1:8080/myapp</a></p></li> 
 <li><p><code>String webroot(String url)</code><br /> 将 url 转换为完整的 web 站点路径，如 <a href="http://127.0.0.1:8080/myapp/path/file">http://127.0.0.1:8080/myapp/path/file</a></p></li> 
</ul>
<p><a name="default_tags"></a></p>
<h1 id="x1937656097" class="page-header"><span>8 默认的自定义标签 Tags</span></h1>
<p>所有 Tags 定义在 <code>jetbrick.template.runtime.JetTags</code></p> 
<ul> 
 <li><p><code>#tag layout(String file)</code> ... <code>#end</code><br /> 应用页面布局。<br /> 参考：<a href="faq-layout.html">jetbrick-template 中如何实现 layout 功能？</a></p></li> 
 <li><p><code>#tag layout(String file, Map&lt;String, Object&gt; parameters)</code> ... <code>#end</code><br /> 应用页面布局(支持传递传输)。<br /> 参考：<a href="faq-layout.html">jetbrick-template 中如何实现 layout 功能？</a></p></li> 
 <li><p><code>#tag block(String name)</code> ... <code>#end</code><br /> 将块内容保存到变量名为 name 的 JetContext 中。<br /> 参考：<a href="faq-layout.html">jetbrick-template 中如何实现 layout 功能？</a></p></li> 
 <li><p><code>#tag default_block(String name)</code> ... <code>#end</code><br /> 如果不存在指定的 JetContext 变量，那么输出 default_block 块内容，否则输出指定的 JetContext 变量。<br /> 参考：<a href="faq-layout.html">jetbrick-template 中如何实现 layout 功能？</a></p></li> 
 <li><p><code>#tag application_cache(String name, long timeout)</code> ... <code>#end</code><br /> 将内存缓存到 ServletContext 中，在 timeout 秒之后自动超时。</p></li> 
 <li><p><code>#tag session_cache(String name, long timeout)</code> ... <code>#end</code><br /> 将内存缓存到 HttpSession 中，在 timeout 秒之后自动超时。</p></li> 
</ul>
<p><a name="velocity"></a></p>
<h1 id="x1968843044" class="page-header"><span>9 和 Velocity 的比较</span></h1>
<h2 id="x1094687580" class="page-header"><span>9.1 语法差异</span></h2> 
<ul> 
 <li>jetbrick-template 指令中的变量不加 <code>$</code> 符，只支持 <code>#if(x == y)</code>，不支持 <code>#if($x == $y)</code>，因为指令中没有加引号的字符串就是变量，和常规语言的语法一样，加$有点废话，而且容易忘写。</li> 
 <li>jetbrick-template 占位符必需加大括号，只支持 <code>${foo}</code>，不支持 <code>$foo</code>，因为 <code>$</code> 在 JavaScript 中也是合法变量名符号，而 <code>${}</code> 不是，减少混淆，也防止多人开发时，有人加大括号，有人不加，干脆没得选，都加，保持一致。</li> 
 <li>jetbrick-template 占位符当变量为 <code>null</code> 时输出空白串，而不像 Velocity 那样原样输出指令原文，即 <code>${foo}</code>，等价于 Velocity 的 <code>$!{foo}</code>，以免开发人员忘写感叹号，泄漏表达式源码，如需原样输出，可使用转义 <code>\${foo}</code>， 在 jetbrick-template 中，<code>$!{foo}</code> 表示对内容进行 HTML 过滤，用于原样输出 HTML 片段。</li> 
 <li>jetbrick-template 支持在所有使用变量的地方，进行表达式计算，也就是你不需要像 Velocity 那样，先 <code>#set($j = $i + 1)</code> 到一个临时变量，再输出临时变量 <code>${j}</code>，jetbrick-template 可以直接输出 <code>${i + 1}</code>，其它指令也一样，比如：<code>#if(i + 1 == n)</code>。</li> 
 <li>jetbrick-template 采用扩展 Class 原生方法的方式，如：<code>${&quot;str&quot;.toChar()}</code>，而不像 Velocity 的 Tool 工具方法那样：<code>$(StringTool.toChar(&quot;a&quot;))</code>，这样的调用方式更直观，更符合代码书写习惯。</li> 
 <li>jetbrick-template 支持属性和方法的安全调用。如 <code>${user?.name}</code>，<code>${user?.hasRole(&quot;vip&quot;)}</code>。如果 <code>user</code> 对象为 <code>null</code>，那么返回结果就是 <code>null</code>，不会出现烦人的 <code>NullPointerException</code>。</li> 
 <li>jetbrick-template 还支持静态字段/方法调用，函数扩展，上下文相关的方法/函数扩展。</li> 
</ul>
<h2 id="x775409745" class="page-header"><span>9.2 指令差异</span></h2>
           	</div>
           </div>
		</div> 
 	</div>
    <!-- Footer
    ================================================== -->
    <footer class="bs-footer" role="contentinfo">
      <div class="container">
        <ul class="footer-links">
          <li>当前版本： v0.0.3</li>
          <li class="muted">&middot;</li>
          <li><a href="http://v2.bootcss.com/">Bootstrap 2.3.2 中文文档</a></li>
          <li class="muted">&middot;</li>
          <li><a href="http://www.bootcss.com">Bootstrap中文网</a></li>
          <li class="muted">&middot;</li>
          <li><a href="http://blog.getbootstrap.com">官方博客</a></li>
          <li class="muted">&middot;</li>
          <li><a href="https://github.com/twbs/bootstrap/issues?state=open">Issues</a></li>
          <li class="muted">&middot;</li>
          <li><a href="https://github.com/twbs/bootstrap/releases">Releases</a></li>
        </ul>
      </div>
    </footer>

    <!-- JS and analytics only. -->
<script src="http://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script>
<script src="./assets/js/bootstrap.js"></script>
<script src="http://cdn.bootcss.com/holder/2.0/holder.min.js"></script>
<script src="http://cdn.bootcss.com/highlight.js/7.3/highlight.min.js"></script>
<script >hljs.initHighlightingOnLoad();</script>
<script src="./assets/js/application.js"></script>
<script src="./assets/js/jquery.scrollToTop.min.js"></script>
<script text="javascript/text">
	$(document).ready(function(){
		$("#toTop").scrollToTop(1000);
  		$("table").addClass("table table-bordered");
  	});
</script>
  </body>
</html>
